package sample.thread;

import com.alibaba.fastjson.JSONArray;
import javafx.application.Platform;
import javafx.scene.web.WebView;
import sample.Main;
import sample.canvasDemo.CanvasDemo;
import sample.tools.*;
import java.util.Arrays;

/**
 * 作者：w on 2021-08-06.
 * 邮箱：y141111@126.com
 * 版本：v1.0
 */
public class TCPHelper implements Runnable {    // 实现Runnable接口，作为线程的实现类
    private String name ;       // 表示线程的名称
    private String ip ;       // 表示线程的名称
    private int port ;       // 表示线程的名称
    private TCPClient tcpClient;
    private double endX;
    private double endY;
    /**
     * 构造方法配置
     * @param name 线程名称
     * @param ip 服务器地址
     * @param port 服务器端口
     */
    public TCPHelper(String name, String ip, int port){
        this.name = name ;      // 通过构造方法配置name属性
        this.ip = ip;
        this.port = port;
    }
    @Override
    public void run() {
        tcpClient = new TCPClient();
        boolean b = tcpClient.conn(ip, port);
        System.out.println(b? "连接服务器成功！":"连接服务器失败！");
        while (true){
            if (tcpClient.isConnTCP){
                byte[] bytes = tcpClient.recover();
                if (Arrays.equals(bytes, "读取超时".getBytes())){
                    tcpClient.send("im 8...");  // 心跳包
                    continue;
                }else{
                    String hexString = StringToHex.bytesToHexString(bytes);
                    if (hexString.startsWith("2441414141")){    //  hex2441414141就是$AAAA车辆当前状态指令
                        System.out.println("收到$AAAA更新设备当前状态！");
                        String[] byteString = new YUtils().hexCommSplitString(hexString);
                        String[] a = byteString;
                        // 数组数据：
                        // 0包头	1识别码	2相对X	3相对Y	4速度	5航向角	6差分状态
                        // 7查分数量	8纬度	9经度	10误差	11雷达距离  12包尾
                        if (!(a.length == 13)){
                            System.out.println("$AAAA格式不正确，数组长度" + a.length + "，停止解析，重新接收。。。");
                            continue;
                        }
                        try {
                            a[0] = StringToHex.hexStringToString(a[0]); // 数据头:string = $AAAA
                            a[1] = StringToHex.hexStringToString(a[1]); // 标识码:string = HNS005
                        }catch (Exception e){
                            System.out.println("包头或识别码异常，停止解析，重新接收。。。");
                            continue;
                        }
                        try {
                            for (int i = 2; i <= 3; i++){  // hexString 2 int   // 纬度、经度(16进制、注意负数补码，高低八位)
                                a[i] = String.valueOf(BinaryUtils.hexString2Int(a[i].substring(2, 4) + a[i].substring(0, 2)));
                            }
                        }catch (Exception e){
                            System.out.println("相对坐标xy异常，停止解析，重新接收。。。");
                            continue;
                        }
                        try {
                            for (int i = 4; i <= 11; i++){    // hexString 2 String 剩下的string类型
                                a[i] = StringToHex.hexStringToString(a[i]);
                            }
                        }catch (Exception e){
                            System.out.println("速度、航向角、差分状态、差分数量、纬度、经度、误差、雷达距离其中一个异常，停止解析，重新接收。。。");
                            continue;
                        }
                        double speed = Double.parseDouble(a[4]);    // 速度
                        a[4] = String.format("%.1f", speed); // 保留1位小数
                        a[6] = a[6].equals("1")? "极差": a[6].equals("2")? "差差": a[6].equals("3")? "中等": a[6].equals("4")? "优秀":"极差";
//                        if (!a[6].equals("4")){ // 查分经度不是最优，舍弃
//                            System.out.println("差分状态为"+ a[6] + "，停止解析，重新接收。。。");
//                            continue;
//                        }
                        double[] longLat;
                        String[] longitudeLatitude;
                        double distance;
                        try{
                            longLat = YUtils.GPGGALongLatConvert(a[8], a[9]);  // 将GPGGA数据格式转换为GPS 捕获异常，做不成就GG
                            if (Arrays.equals(longLat, new double[]{0, 0})){
                                continue;
                            }
                            distance = LongLatCalculationDistance.findDistance(longLat[0], longLat[1], endX, endY);
                            System.out.println(distance);
                            longitudeLatitude = new String[]{String.valueOf(longLat[0]), String.valueOf(longLat[1])};
                        }catch (Exception e){
                            System.out.println("GPGGA坐标异常，停止解析，重新接收。。。");
                            continue;
                        }
                        try {
                            if (Double.parseDouble(a[10]) > 12){
                                a[10] = String.valueOf((Double.parseDouble(a[10]) - 12) / 40);
                            }
                        }catch (Exception e){
                            System.out.println("误差值转换异常，停止解析，重新接收。。。");
                            continue;
                        }
                        int radarNum;
                        String radar;
                        try {
                            radarNum = Double.parseDouble(a[11]) <= 200 ? 0 :
                                    Double.parseDouble(a[11]) <= 250 ? 1 :
                                            Double.parseDouble(a[11]) <= 300 ? 2 :
                                                    Double.parseDouble(a[11]) <= 350 ? 3 :
                                                            Double.parseDouble(a[11]) <= 400 ? 4 :
                                                                    Double.parseDouble(a[11]) <= 450 ? 5 :
                                                                            Double.parseDouble(a[11]) <= 500 ? 6 :
                                                                                    Double.parseDouble(a[11]) <= 550 ? 7 :
                                                                                            Double.parseDouble(a[11]) <= 600 ? 8 :
                                                                                                    Double.parseDouble(a[11]) <= 650 ? 9 :
                                                                                                            Double.parseDouble(a[11]) <= 700 ? 10 :
                                                                                                                    Double.parseDouble(a[11]) <= 750 ? 11 : 12;   // 雷达距离

                            radar = Double.parseDouble(a[11]) > 800 ? "未检测到障碍物" : a[11];
                        }catch (Exception e){
                            System.out.println("雷达距离异常，停止解析，重新接收。。。");
                            continue;
                        }
//                        Main.infoEvent.setName(Main.infoListener, Main.infoEvent, a[1]);
//                        Main.infoEvent.setX(Main.infoListener, Main.infoEvent, Double.parseDouble(a[2]));
//                        Main.infoEvent.setY(Main.infoListener, Main.infoEvent, Double.parseDouble(a[3]));
//                        Main.infoEvent.setSpeed(Main.infoListener, Main.infoEvent, Double.parseDouble(a[4]));
//                        Main.infoEvent.setAngle(Main.infoListener, Main.infoEvent, Double.parseDouble(a[5]));
//                        Main.infoEvent.setState(Main.infoListener, Main.infoEvent, Double.parseDouble(a[6]));
//                        Main.infoEvent.setDifNum(Main.infoListener, Main.infoEvent, Double.parseDouble(a[7]));
//                        Main.infoEvent.setGPGGAX(Main.infoListener, Main.infoEvent, Double.parseDouble(a[8]));
//                        Main.infoEvent.setGPGGAY(Main.infoListener, Main.infoEvent, Double.parseDouble(a[9]));
//                        Main.infoEvent.setErrNum(Main.infoListener, Main.infoEvent, Double.parseDouble(a[10]));
//                        Main.infoEvent.setRadarNum(Main.infoListener, Main.infoEvent, radarNum);
                        try {
                            Platform.runLater(new Runnable() {
                                @Override
                                public void run() {
                                    Main.name_show.setText(a[1]);
                                    Main.x_show.setText(a[2]);
                                    Main.y_show.setText(a[3]);
                                    Main.speed_show.setText(a[4]);
                                    Main.angle_show.setText(a[5]);
                                    Main.state_show.setText(a[6]);
                                    Main.difNum_show.setText(a[7]);
                                    Main.GPGGAlongitude_show.setText(a[8]);
                                    Main.GPGGAlatitude_show.setText(a[9]);
                                    Main.GPSlongitude_show.setText(longitudeLatitude[0]);
                                    Main.GPSlatitude_show.setText(longitudeLatitude[1]);
                                    Main.errNum_show.setText(a[10]);
                                    Main.radar_show.setText(radar);
                                    JavaUseJS.Run((WebView)Main.root.lookup("#webView"), "addMarker(" + longitudeLatitude[0] + ", " + longitudeLatitude[1] + ")");
                                    CanvasDemo.drawEp(Main.canvas_show, Integer.parseInt(a[10]), 0, distance > 1 ? "epDark.png":distance > 0.5 ? "epDark2.png":"eplv.png", radarNum);
                                }
                            });
                        }catch (Exception e){
                            System.out.println("$AAAA显示信息失败。");
                            continue;
                        }
                    }
                    else if (hexString.startsWith("2442424242")){// $BBBB    预设路径 点读取
                        System.out.println("收到$BBBB更新设备预设路径！");
                        try {
                            String str = StringToHex.hexStringToString(hexString);
                            double[][] GPGGAlonglat = DefaultRouter.allInfo(str);
                            double[][] GPSLonglat = CoordinateTransformation.TransformLongLat(GPGGAlonglat);
                            // 旧的单点画 添加预设路线方法，会出现首尾相连的情况
//                            for (int i = 0; i < GPSLonglat[0].length; i++){
//                                try {
//                                    Thread.sleep(200);   // 添加延迟解决时序问题
//                                    int finalI = i;
//                                    endX = GPSLonglat[0][finalI];
//                                    endY = GPSLonglat[1][finalI];
//                                    Platform.runLater(new Runnable() {
//                                        @Override
//                                        public void run() {
//                                            JavaUseJS.Run((WebView)Main.root.lookup("#webView"), "addRouter(" + GPSLonglat[0][finalI] + ", " + GPSLonglat[1][finalI] + ")");
//                                        }
//                                    });
//                                } catch (InterruptedException e) {
//                                    System.out.println("$BBBB添加预设路线失败");
//                                }
//                            }
                            // 以下为新的添加路线方法
                            StringBuilder coords = new StringBuilder();
                            for (int i = 0; i < GPSLonglat[0].length; i++){
                                coords.append(GPSLonglat[1][i]);
                                coords.append(",");
                                coords.append(GPSLonglat[0][i]);
                                if (i != GPSLonglat[0].length - 1){
                                    coords.append(";");
                                }
                            }
                            JSONArray jsonArray = BMapChangePosition.changeGPSCoords(coords.toString());
                            Platform.runLater(() -> JavaUseJS.Run((WebView)Main.root.lookup("#webView"), "addRouterAllPointBMap(" + jsonArray + ")"));

                        }catch (Exception e){
                            System.out.println("$BBBB解析失败，重新接收。。。" + e.toString());
                            continue;
                        }
                    }
                }
                System.out.println(name + "：接收到数据:" + new String(bytes));
            }else {
                System.out.println(name + "：连接失败，开始重新连接");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                tcpClient.conn(ip, port);
            }

        }
    }

    /**
     * 发送16进制
     * @param bytes bytes
     */
    public void sendHexMessage(byte[] bytes){
        tcpClient.sendHexMessage(bytes);
    }
}
